home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / tcoop.arc / TCOOP2.ARC / TXSCROLL.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-26  |  9.4 KB  |  334 lines

  1. // txscroll.cpp: Scrollable window class methods
  2.  
  3. #include <math.h>
  4. #include "txscroll.h"
  5.  
  6. // --------------------  ScrollFrame Methods -------------------- 
  7.  
  8. // Correction: pg 294, Cp passed by reference, not by
  9. //             pointer as in book
  10. ScrollFrame::ScrollFrame(BarOrient Orient, ColorPak &Cp)
  11. // Initializes a scroll bar's frame object. 
  12. : Tfso(0x00, 0x00, Cp)
  13. {
  14.   Orientation = Orient;
  15. }
  16.  
  17. void ScrollFrame::SetSize(int W, int H)
  18. // The size (W,H) is interpreted to be the interior size. The
  19. // other sizes are based off of it. Dep}ing on the orientation,
  20. // one of the sizes is ignored. 
  21. {
  22.   if (Orientation == HzOrient) {
  23.      Interior->SetSize(W, 1);  // Height ignored 
  24.      Frame->SetSize(W+2, 1);
  25.      Overall->SetSize(W+2, 1);
  26.   }
  27.   else {
  28.     Interior->SetSize(1, H);   // Width ignored  
  29.     Frame->SetSize(1, H+2);
  30.     Overall->SetSize(1, H+2);
  31.   }
  32. }
  33.  
  34. void ScrollFrame::SetLocn(int Xl, int Yl)
  35. // Set the upper left hand corner location of the frame.
  36. // The location is interpreted to be that of the frame
  37. // rectangle. 
  38. {
  39.   Frame->SetLocn(Xl, Yl);
  40.   Overall->SetLocn(Frame->Xul, Frame->Yul);
  41.   if (Orientation == HzOrient)
  42.      Interior->SetLocn(Frame->Xul+1, Frame->Yul);
  43.      else Interior->SetLocn(Frame->Xul, Frame->Yul+1);
  44. }
  45.  
  46. void ScrollFrame::DrawFrame(char, char)
  47. // The frame is just two arrows 
  48. {
  49.   if (Orientation == HzOrient) {
  50.      Frame->HzWrt(0, 0, "\x1b", 0x70);           // Left arrow 
  51.      Frame->HzWrt(Frame->Wd-1, 0, "\x1a", 0x70); // Right arrow 
  52.   }
  53.   else {
  54.      Frame->HzWrt(0, 0, "\x18", 0x70);           // Up arrow 
  55.      Frame->HzWrt(0, Frame->Ht-1, "\x19", 0x70); // Down arrow 
  56.   }
  57. }
  58.  
  59. // -------------------- Slider Methods ---------------------- 
  60.  
  61. void Slider::Draw(void)
  62. // Draws a single character for the slider button
  63. {
  64.   Panel->Interior->HzWrtB(0, 0, "\xb1"); 
  65. }
  66.  
  67. void Slider::OnMouseDown(MsgPkt &M)
  68. // Call BorderHandler to move slider object whenever mouse is
  69. // pressed while on the slider 
  70. {
  71.   SwitchFocus(M);
  72.   BorderHandler(M);
  73. }
  74.  
  75. void Slider::Move(int X, int Y)
  76. // Move to new absolute coordinates. Send a message to the 
  77. // scroll bar indicating its new position. 
  78. {
  79.   Wso::Move(X, Y);
  80.   ((ScrollBar *)Base)->SendScrollPosn();
  81. }
  82.  
  83. void Slider::OnKeyStroke(MsgPkt &M)
  84. // Send keystrokes detected while Slider is active to the scroll bar 
  85. {
  86.   Base->OnKeyStroke(M);
  87. }
  88.  
  89. // --------------------- ScrollBar Methods --------------------- 
  90.  
  91. // Correction: pg 295, Cp passed by reference, not
  92. //             by pointer as in book
  93. ScrollBar::ScrollBar(BarOrient Orient, ColorPak &Cp)
  94. // Initialize ScrollBar to use a ScrollFrame frame. Allocate
  95. // Slider object. 
  96. : Iso(new ScrollFrame(Orient, Cp))
  97. {
  98.   Slide = new Slider(Cp);
  99.   Slide->SetSize(1, 1); // Always one texel big 
  100.   DelayCntr = 0;  DelayLimit = 50; // Default delay 
  101.   InhibitMessage = False;
  102. }
  103.  
  104. void ScrollBar::Draw()
  105. // Draw the patterned interior of the scroll bar 
  106. {
  107.   Iso::Draw();
  108.   Panel->Clear(176, 0); // A patterned interior 
  109. }
  110.  
  111. void ScrollBar::Redraw()
  112. // Call default redraw action, then redraw the slider 
  113. {
  114.   Iso::Redraw(); 
  115.   Slide->Redraw();
  116. }
  117.  
  118. void ScrollBar::Open(Iso *B, int X, int Y)
  119. // Open the scrollbar, and then open the slider on top of it 
  120. {
  121.   Iso::Open(B, X, Y);
  122.   Slide->Open(this, 0, 0);
  123. }
  124.  
  125. void ScrollBar::BorderHandler(MsgPkt &M)
  126. // Mouse is on one of the arrows. Send a simulated keypress to the
  127. // scroll bar's base corresponding to which arrow is selected. 
  128. {
  129.   ScrollFrame *Sf = (ScrollFrame *)Panel;
  130.   MsgPkt FakeMsg = NullMsg;
  131.   
  132.   FakeMsg.Focus = Base;
  133.   if (Sf->Orientation == HzOrient) {
  134.      if (M.Mx == Sf->Frame->Xul) { // Mouse on left arrow 
  135.         FakeMsg.Code = LeftKey;    // Act like key was pressed 
  136.         Base->Dispatch(FakeMsg);
  137.      }
  138.      else if (M.Mx == Sf->Frame->Xlr) { // On right arrow 
  139.         FakeMsg.Code = RightKey;
  140.         Base->Dispatch(FakeMsg);
  141.      }
  142.   }
  143.   else {
  144.      if (M.My == Sf->Frame->Yul) {      // On up arrow 
  145.         FakeMsg.Code = UpKey;
  146.         Base->Dispatch(FakeMsg);
  147.      }
  148.      else if (M.My == Sf->Frame->Ylr) { // On Down arrow 
  149.         FakeMsg.Code = DownKey;
  150.         Base->Dispatch(FakeMsg);
  151.      }
  152.   }
  153. }
  154.  
  155. void ScrollBar::OnMouseDown(MsgPkt &M)
  156. // Mouse is pressed when it is within the scroll bar. 
  157. // Move the slider to that location. 
  158. {
  159.   if (Panel->OnInterior(M.Mx, M.My))  {
  160.      Slide->Move(M.Mx, M.My);
  161.      // Need to to this so you can leave the mouse button down
  162.      // and still move.
  163.      Slide->OnMouseDown(M);
  164.   }
  165.   else if (Panel->OnBorder(M.Mx, M.My)) BorderHandler(M);
  166.   DelayCntr = 0;  // Start count over 
  167. }
  168.  
  169. void ScrollBar::OnMouseStillDown(MsgPkt &M)
  170. // Mouse is still pressed on one of the scroll bar arrows. 
  171. // If the DelayCntr has reached DelayLimit, then update
  172. // the slider position. 
  173. {
  174.   DelayCntr++;
  175.   if (DelayCntr > DelayLimit) {
  176.      if (Panel->OnBorder(M.Mx, M.My)) {
  177.         BorderHandler(M);
  178.      }
  179.      DelayCntr = 0;
  180.   }
  181. }
  182.  
  183. void ScrollBar::OnKeyStroke(MsgPkt &M)
  184. // Send keystrokes to base window.
  185. {
  186.   Base->OnKeyStroke(M);
  187. }
  188.  
  189. void ScrollBar::SendScrollPosn(void)
  190. // Send a message to the base window of the scroll bar indicating its
  191. // position. The location of the slider in the scroll bar is encoded
  192. // to be a number between 0 and 10000 where a value of 10000 
  193. // indicates that the slider is at full-scale. 
  194. {
  195.   int Ip;
  196.   float Rp;
  197.   MsgPkt M;
  198.   Rso *Pint = Panel->Interior; 
  199.  
  200.   if (InhibitMessage) return;
  201.   M.Focus = Base;
  202.  
  203.   if (((ScrollFrame *)Panel)->Orientation == HzOrient) {
  204.      // Compute relative position of slider to sliderbar 
  205.      Ip = Slide->Panel->Frame->Xul - Pint->Xul;
  206.      if (Pint->Wd == 1) 
  207.         Rp = 0.0;
  208.         else Rp =  float(Ip) / float(Panel->Interior->Wd-1);
  209.      M.Code = HzScrollMove; // M.RtnCode = Idle assumed
  210.      M.Mx = floor(Rp * 10000.0); M.My = 0;
  211.   }
  212.   else {  // Object is a vertical scroll bar 
  213.     Ip = Slide->Panel->Frame->Yul - Pint->Yul;
  214.     if (Pint->Ht == 1)
  215.        Rp = 0.0;
  216.        else Rp =  float(Ip) / float(Panel->Interior->Ht-1);
  217.     M.Code = VtScrollMove; // M.RtnCode = Idle assumed
  218.     M.Mx = 0; M.My = floor(Rp * 10000.0);
  219.   }
  220.   Base->Dispatch(M);
  221. }
  222.  
  223.  
  224. void ScrollBar::RcvScrollPosn(float P, BarOrient Which)
  225. // This method takes the number P, between 0.0 and 1.0, and
  226. // causes the Slider to move to the appropriate position. 
  227. {
  228.   int NewPos;
  229.  
  230.   if (Which == HzOrient) {
  231.      // Compute relative position to move slider within slidebar 
  232.      NewPos = ceil(P * ((float)Panel->Interior->Wd-1));
  233.      InhibitMessage = True;
  234.      // Prevent Move from s}ing message back 
  235.      Slide->Move(Panel->Interior->Xul+NewPos,Panel->Interior->Yul);
  236.      InhibitMessage = False;
  237.   }
  238.   else {
  239.      // Compute relative position to move slider within slidebar 
  240.      NewPos = ceil(P * (float)(Panel->Interior->Ht-1));
  241.      InhibitMessage = True;
  242.      Slide->Move(Panel->Interior->Xul,NewPos+Panel->Interior->Yul);
  243.      InhibitMessage = False;
  244.   }
  245. }
  246.  
  247. // --------------- Abstract Scroll Window Methods ---------------- 
  248.  
  249. // Correction: Pg 298, Cp passed by reference, not by
  250. //             pointer as in book
  251. Swso::Swso(int Fa, ColorPak &Cp)
  252. // Initialize Swso object by setting its border and allocating
  253. // the nested scroll bar objects. 
  254. : Wso(0x11, Fa, Cp)
  255. {
  256.   HzSlide = new ScrollBar(HzOrient, Cp);
  257.   // Set True so can draw slider bars on border of window 
  258.   HzSlide->ClipToFrame = True;
  259.   VtSlide = new ScrollBar(VtOrient, Cp);
  260.   VtSlide->ClipToFrame = True;
  261. }
  262.  
  263. void Swso::SetSize(int W, int H)
  264. // Set the size of the Swso object and the nested scroll bars. 
  265. // Note: we have to relocate the scroll bars too. SetLocn has
  266. // no way of knowing they need to be relocated if the window
  267. // is resized. 
  268. {
  269.   Wso::SetSize(W, H);
  270.   HzSlide->SetSize(W-2, 1);
  271.   HzSlide->SetLocn(1, Panel->Frame->Ht-1, Relc);
  272.   VtSlide->SetSize(1, H-2);
  273.   VtSlide->SetLocn(Panel->Frame->Wd-1, 1, Relc);
  274. }
  275.  
  276. void Swso::Stretch(int W, int H)
  277. // Stretch a scroll window. We must fake out the stretch
  278. // algorithm by setting the scroll bars to a minimum size
  279. // temporarily, otherwise, we can't make the window smaller. 
  280. {
  281.   HzSlide->SetSize(1,1); 
  282.   VtSlide->SetSize(1,1); 
  283.   Wso::Stretch(W,H);
  284. }
  285.  
  286. void Swso::Open(Iso *B, int X, int Y)
  287. // Open Swso object and the two nested scroll bars 
  288. {
  289.   Wso::Open(B, X, Y);
  290.   HzSlide->Open(this, 1, Panel->Frame->Ht-1);
  291.   VtSlide->Open(this, Panel->Frame->Wd-1, 1);
  292. }
  293.  
  294. void Swso::Redraw(void)
  295. // Redraw the window plus scroll bars 
  296. {
  297.   Wso::Redraw();
  298.   HzSlide->Redraw();
  299.   VtSlide->Redraw();
  300. }
  301.  
  302. void Swso::Prompt(void)
  303. // We don't want to prompt Swso object because this would 
  304. // overwrite the scroll bars, so we'll skip back two levels 
  305. // in the hierarchy and call Iso's prompter 
  306. {
  307.   Iso::Prompt(); 
  308. }
  309.  
  310. void Swso::UnPrompt(void)
  311. // We don't want to call Wso's prompter, since it would
  312. // overwrite the scroll bars, so we'll skip back two
  313. // levels in the hierarchy and call Iso's prompter 
  314. {
  315.   Iso::UnPrompt();
  316. }
  317.  
  318. void Swso::Dispatch(MsgPkt &M)
  319. // Trap for ScrollMove event codes passed to the Swso object. These
  320. // events cause the scroll window to update what it displays. 
  321. {
  322.   if (M.Code == HzScrollMove) {
  323.      RcvScrollPosn(float(M.Mx) / 10000.0, HzOrient);
  324.      M.RtnCode = M.Code = Idle;
  325.   }
  326.   else if (M.Code == VtScrollMove) {
  327.      RcvScrollPosn(float(M.My) / 10000.0, VtOrient);
  328.      M.RtnCode = M.Code = Idle;
  329.   }
  330.   else Wso::Dispatch(M);
  331. }
  332.  
  333.  
  334.